<!DOCTYPE html>
<html ng-app="App" lang="en">
<head>
    <meta charset="UTF-8">
    <title>disable</title>
    <script src="../../js/angular/angular.min.js"></script>
    <script type="text/javascript" src="demo8.js"></script>
</head>
<body>

    <textarea ng-disabled="isDisabled">Wait5seconds</textarea>
</body>
</html>
1.基础ng 属性指令
首先来看看和原生HTML标签名称相似的一组内置指令，这组指令非常容易记忆，因为仅仅是在原生标签名前加上了ng前缀，包括：
     ng-href；
     ng-src；
     ng-disabled；
     ng-checked；
     ng-readonly；
     ng-selected；
     ng-class；
     ng-style。
2.布尔属性
根据HTML标准的定义①，布尔属性代表一个true或false值。当这个属性出现时，这个属性的值就是true（无论实际定义的值是什么）。如果未出现，这个属性的值就是false。
    1. ng-disabled
    使用ng-disabled可以把disabled属性绑定到以下表单输入字段上：
     <input> （text、checkbox、radio、number、url, email、submit）；
     <textarea>；
     <select>；
     <button>。
在下面的例子中按钮会一直禁用，直到用户在文本字段中输入内容：
            <input type="text" ng-model="someProperty" placeholder="TypetoEnable">
            <button ng-model="button" ng-disabled="!someProperty">AButton</button>
文本字段会被禁用五秒，直到在$timeout中将isDisabled属性设置为true：
            <textarea ng-disabled="isDisabled">Wait5seconds</textarea>
            angular.module('myApp', [])
            .run(function($rootScope, $timeout) {
            $rootScope.isDisabled = true;
            $timeout(function() {
            $rootScope.isDisabled = false;
            }, 5000);
            });
    2.ng-readonly
同其他布尔属性一样，HTML定义只会检查readonly属性是否出现，而不是它的实际值。通过ng-readonly可以将某个返回真或假的表达式同是否出现readonly属性进行绑定：
            Type here to make sibling readonly:
            <input type="text" ng-model="someProperty"><br/>
            <input type="text" ng-readonly="someProperty" value="Some text here"/>
    3.ng-checked
标准的checked属性是一个布尔属性，不需要进行赋值。通过ng-checked将某个表达式同是否出现checked属性进行绑定。

            在下面的例子中，我们通过ng-init指令将someProperty的值设置为true。将some Property同ng-checked绑定在一起，
            AngularJS会输出标准的HTML checked属性，这样默认会把复选框勾选：
            <label>someProperty = {{someProperty}}</label>
            <input type="checkbox"
                   ng-checked="someProperty"
                   ng-init="someProperty = true"
                   ng-model="someProperty">
            下面的例子刚好相反：
            <label>someProperty = {{anotherProperty}}</label>
            <input type="checkbox"
                   ng-checked="anotherProperty"
                   ng-init="anotherProperty = false"
                   ng-model="anotherProperty">
            注意，为了展示，这里用ng-model把someProperty和anotherProperty的值绑定到了对应的<label>标签里。

    4. ng-selected
ng-selected可以对是否出现option标签的selected属性进行绑定：
                <label>Select Two Fish:</label>
                <input type="checkbox"
                       ng-model="isTwoFish"><br/>
                <select>
                    <option>One Fish</option>
                    <option ng-selected="isTwoFish">Two Fish</option>
                </select>
3.类布尔属性
ng-href、ng-src等属性虽然不是标准的HTML布尔属性，但是由于行为相似，所以在AngularJS源码内部是和布尔属性同等对待的，下面介绍这些属性。
                ng-href和ng-src都能有效帮助重构和避免错误，因此在改进代码时强烈建议用它们代替原来的href和src属性。
        1. ng-href
                当使用当前作用域中的属性动态创建URL时，应该用ng-href代替href。
                这里的潜在问题是当用户点击一个由插值动态生成的链接时，如果插值尚未生效，将会跳转到错误的页面（通常是404）。
                这时，如果使用ng-href，AngularJS会等到插值生效（在例子中是两秒以后）后再执行点击链接的行为：
                <!-- 当 href 包含一个 {{expression}}时总是使用 ng-href -->
                <a ng-href="{{ myHref }}">I'm feeling lucky, when I load</a>
                <!-- 用户单击之前，href不会加载 -->
                <a href="{{ myHref }}">I'm feeling 404</a>
                将插值生效的事件延迟两秒，来观察实际的行为：
                angular.module('myApp', [])
                .run(function($rootScope, $timeout) {
                $timeout(function() {
                $rootScope.myHref = 'http://baidu.com';
                }, 5000);
                });
        2. ng-src
                AngularJS会告诉浏览器在ng-src对应的表达式生效之前不要加载图像：
                <h1>WrongWay</h1>
                <img src="{{imgSrc}}"/>
                <h1>Rightway</h1>
                <img ng-src="{{imgSrc}}"/>
                angular.module('myApp', [])
                .run(function($rootScope, $timeout) {
                $timeout(function() {
                $rootScope.imgSrc = 'https://www.google.com/images/srpr/logo11w.png';
                }, 2000);
                });
   浏览在线示例时，通过Chrome开发者工具的网络面板观察资源加载状况，注意，其中一个请求是红色的，说明发生了错误。
   这个错误是由于Wrong Way中我们用src代替了ng-src导致的

4.在指令中使用子作用域
                下面将要介绍的指令会以父级作用域为原型生成子作用域。这种继承的机制可以创建一个隔离层，用来将需要协同工作的方法和数据模型对象放置在一起。
                ng-app和ng-controller是特殊的指令，因为它们会修改嵌套在它们内部的指令的作用域。
                ng-app为AngularJS应用创建$rootScope，ng-controller则会以$rootScope或另外一个ng-controller的作用域为原型创建新的子作用域。

         1. ng-app:任何具有ng-app属性的DOM元素将被标记为$rootScope的起始点。
                   $rootScope是作用域链的起始点，任何嵌套在ng-app内的指令都会继承它。在JavaScript代码中通过run方法来访问$rootScope。
                <html ng-app="myApp">
                <body>
                {{ someProperty }}
                <button ng-click="someAction()"></button>
                </body>
                </html>

                angular.module('myApp', [])
                .run(function($rootScope) {
                $rootScope.someProperty = 'hello computer';
                $rootScope.someAction = function() {
                $rootScope.someProperty = 'hello human';
                };
                });
         2. ng-controller:内置指令ng-controller的作用是为嵌套在其中的指令创建一个子作用域，避免将所有操作和模型都定义在$rootScope上。
                用这个指令可以在一个DOM元素上放置控制器。
                ng-controller接受一个参数expression，这个参数是必需的。expression参数是一个AngularJS表达式。
                子$scope只是一个JavaScript对象，其中含有从父级$scope中通过原型继承得到的方法和属性，包括应用的$rootScope。
                嵌套在ng-controller中的指令有访问新子$scope的权限，但是要牢记每个指令都应该遵守的和作用域相关的规则。
                回想一下，$scope对象的职责是承载DOM中指令所共享的操作和模型。
                <div ng-controller="SomeController">
                    {{ someModel.someProperty }}
                    <button ng-click="someAction()">Communicate</button>
                </div>

                angular.module('myApp', [])
                .controller('SomeController', function($scope) {
                //创建模型
                $scope.someModel = {
                // 添加属性
                someProperty: 'hello computer'
                }
                // 设置$scope自身的操作
                $scope.someAction = function() {
                $scope.someModel.someProperty = 'hello human';
                };
                });
                虽然这个特性是使用ng-controller时最重要的特性之一，但在使用任何会创建子作用域的指令时，如果将指令定义中的scope设置为true，
                这个特性也会带来负面影响。下面的内置指令都有同样的特性：
                 ng-include
                 ng-switch
                 ng-repeat
                 ng-view
                 ng-controller
                 ng-if
         3.ng-include
                使用ng-include可以加载、编译并包含外部HTML片段到当前的应用中。模板的URL被限制在与应用文档相同的域和协议下，
                可以通过白名单或包装成被信任的值来突破限制。更进一步，需要考虑跨域资源共享（Cross-Origin Resource Sharing，CORS）
                和同源规则（Same Origin Policy）来确保模板可以在任何浏览器中正常加载。例如，所有浏览器都不能进行跨域的请求，部分浏览
                器也不能访问file://协议的资源。
                在同一个元素上添加onload属性可以在模板加载完成后执行一个表达式。
                要记住，使用ng-include时AngularJS会自动创建一个子作用域。如果你想使用某个特定的作用域，
                例如ControllerA的作用域，必须在同一个DOM元素上添加ng-controller ="ControllerA"指令，
                这样当模板加载完成后，不会像往常一样从外部作用域继承并创建一个新的子作用域。下
                面看一个例子：
                <div ng-include="/myTemplateName.html"
                     ng-controller="MyController"
                     ng-init="name = 'World'">
                    Hello {{ name }}
                </div>
         4.ng-switch
                这个指令和ng-switch-when及on="propertyName"一起使用，可以在propertyName发生变化时渲染不同指令到视图中。
                在下面的例子中，当person.name是Ari时，文本域下面的div会显示出来，并且这个人会获得胜利：
                <input type="text" ng-model="person.name"/>
                <div ng-switch on="person.name">
                    <p ng-switch-default>And the winner is</p>
                    <h1 ng-switch-when="Ari">{{ person.name }}</h1>
                </div>
                注意，在switch被调用之前我们用ng-switch-default来输出默认值。
         5.ng-view
                ng-view指令用来设置将被路由管理和放置在HTML中的视图的位置
         6.ng-if
                使用ng-if指令可以完全根据表达式的值在DOM中生成或移除一个元素。如果赋值给ng-if的表达式的值是false，
                那对应的元素将会从DOM中移除，否则对应元素的一个克隆将被重新插入DOM中。
                ng-if同no-show和ng-hide指令最本质的区别是，它不是通过CSS显示或隐藏DOM节点，而是真正生成或移除节点。

                当一个元素被ng-if从DOM中移除，同它关联的作用域也会被销毁。而且当它重新加入DOM中时，会通过原型继承从它的父作用域生成一个新的作用域。
                同时有一个重要的细节需要知道，ngIf重新创建元素时用的是它们编译后的状态。如果ng-if内部的代码加载之后被jQuery修改过（例如用.addClass），
                那么当ng-if的表达式值为false时，这个DOM元素会被移除，表达式再次成为true时这个元素及其内部的子元素会被重新插入DOM，
                此时这些元素的状态会是它们的原始状态，而不是它们上次被移除时的状态。也就是说
                无论用jQuery的.addClass添加了什么类都不会存在了。
                <div ng-if="2+2===5">
                    Won't see this DOM node, not even in the source code
                </div>
                <div ng-if="2+2===4">
                    Hi, I do exist
                </div>
         7. ng-repeat
                ng-repeat用来遍历一个集合或为集合中的每个元素生成一个模板实例。集合中的每个元素
                都会被赋予自己的模板和作用域。同时每个模板实例的作用域中都会暴露一些特殊的属性。
                 $index：遍历的进度（0...length-1）。
                 $first：当元素是遍历的第一个时值为true。
                 $middle：当元素处于第一个和最后元素之间时值为true。
                 $last：当元素是遍历的最后一个时值为true。
                 $even：当$index值是偶数时值为true。
                 $odd：当$index值是奇数时值为true。
                下面的例子展示了如何用$odd和$even来制作一个红蓝相间的列表。记住，JavaScript中数组
                的索引从0开始，因此我们用!$even和!$odd来将$even和$odd的布尔值反转。
                <ul ng-controller="PeopleController">
                    <li ng-repeat="person in people" ng-class="{even: !$even, odd: !$odd}">
                        {{person.name}} lives in {{person.city}}
                    </li>
                </ul>
                .odd {
                background-color: blue;
                }
                .even {
                background-color: red;
                }

                angular.module('myApp',[])
                .controller('PeopleController',function($scope) {
                $scope.people = [
                {name: "Ari", city: "San Francisco"},
                {name: "Erik", city: "Seattle"}
                ];
                });
         8.ng-init
                ng-init指令用来在指令被调用时设置内部作用域的初始状态。
                ng-init最常见的使用场景是：在类似本节的例子中那样，需要创建小的示例代码的时候。对于任何需要健壮结构的场景，
                请在控制器中用数据模型对象来设置状态。
                <div ng-init="greeting='Hello';person='World'">
                    {{greeting}} {{person}}
                </div>
         9.{{ }}
                <div>{{name}}</div>
                {{ }}语法是AngularJS内置的模板语法，它会在内部$scope和视图之间创建绑定。基于这个绑定，只要$scope发生变化，视图就会随之自动更新。
                事实上它也是指令，虽然看起来并不像，实际上它是ng-bind的简略形式，用这种形式不需要创建新的元素，因此它常被用在行内文本中。
                注意，在屏幕可视的区域内使用{{ }}会导致页面加载时未渲染的元素发生闪烁，用ng-bind可以避免这个问题。
                <body ng-init="greeting='HelloWorld'">
                {{ greeting }}
                </body>
         10. ng-bind
                尽管可以在视图中使用{{ }}模板语法（AngularJS内置的方式），我们也可以通过ng-bind指令实现同样的行为。
                <body ng-init="greeting='HelloWorld'">
                <p ng-bind="greeting"></p>
                </body>
                HTML加载含有{{ }}语法的元素后并不会立刻渲染它们，导致未渲染内容闪烁（Flash ofUnrendered Content，FOUC）。
                我可以用ng-bind将内容同元素绑定在一起避免FOUC。内容会被当作子文本节点渲染到含有ng-bind指令的元素内。
         11. ng-cloak
                除使用ng-bind来避免未渲染元素闪烁，还可以在含有{{ }}的元素上使用ng-cloak指令：
                <body ng-init="greeting='HelloWorld'">
                <p ng-cloak>{{ greeting }}</p>
                </body>
                ng-cloak指令会将内部元素隐藏，直到路由调用对应的页面时才显示出来。
         12. ng-bind-template
                同ng-bind指令类似，ng-bind-template用来在视图中绑定多个表达式。
                <div
                        ng-bind-template="{{message}}{{name}}">
                </div>
         13. ng-model
                ng-model指令用来将input、select、textarea或自定义表单控件同包含它们的作用域中的属性进行绑定。
                它可以提供并处理表单验证功能，在元素上设置相关的CSS类（ng-valid、ng-invalid等），并负责在父表单中注册控件。
                它将当前作用域中运算表达式的值同给定的元素进行绑定。如果属性并不存在，它会隐式创建并将其添加到当前作用域中。
                我们应该始终用ngModel来绑定$scope上一个数据模型内的属性，而不是$scope上的属性，
                这可以避免在作用域或后代作用域中发生属性覆盖。
                例如：
                <input type="text"
                       ng-model="modelName.someProperty" />
                {{modelName.someProperty}}
                上面的例子展示了如何正确地考虑和使用ngModel。
         14. ng-show/ng-hide
                ng-show和ng-hide根据所给表达式的值来显示或隐藏HTML元素。当赋值给ng-show指令的值为false时元素会被隐藏。
                类似地，当赋值给ng-hide指令的值为true时元素也会被隐藏。
                元素的显示或隐藏是通过移除或添加ng-hide这个CSS类来实现的。.ng-hide类被预先定义
                在了AngularJS的CSS文件中，并且它的display属性的值为none（用了!important标记）。
                <div ng-show="2 + 2 == 5">
                    2 + 2 isn't 5, don't show
                </div>
                <div ng-show="2 + 2 == 4">
                    2 + 2 is 4, do show
                </div>
                <div ng-hide="2 + 2 == 5">
                    2 + 2 isn't 5, don't hide
                </div>
                <div ng-hide="2 + 2 == 4">
                    2 + 2 is 4, do hide
                </div>
         15. ng-change
                这个指令会在表单输入发生变化时计算给定表达式的值。因为要处理表单输入，这个指令要和ngModel联合起来使用。
                <div ng-controller="EquationController">
                    <input type="text"
                           ng-model="equation.x"
                           ng-change="change()" />
                    <code>{{ equation.output }}</code>
                </div>

                angular.module('myApp',[])
                .controller('EquationController',function($scope) {
                $scope.equation = {};
                $scope.change = function() {
                $scope.equation.output
                = parseInt($scope.equation.x) + 2;
                };
                });
         16. ng-form
                ng-form用来在一个表单内部嵌套另一个表单。普通的HTML <form>标签不允许嵌套，但ng-form可以。
                    这意味着内部所有的子表单都合法时，外部的表单才会合法。这对于用ng-repeat动态创建表单是非常有用的
                    由于不能通过字符插值来给输入元素动态地生成name属性，所以需要将ng-form指令内每组重复的输入字段都包含在一个外部表单元素内。

                    下面的CSS类会根据表单的验证状态自动设置：
                     表单合法时设置ng-valid；
                     表单不合法时设置ng-invlid；
                     表单未进行修改时设置ng-pristion；
                     表单进行过修改时设置ng-dirty。
                     表单进行过修改时设置ng-dirty。
                Angular不会将表单提交到服务器，除非它指定了action属性。要指定提交表单时调用哪个JavaScript方法，使用下面两个指令中的一个。
                     ng-submit：在表单元素上使用。
                     ng-click：在第一个按钮或submit类型（input[type=submit]）的输入字段上使用。
                    为了避免处理程序被多次调用，只使用下面两个指令中的一个。
                    下面的例子展示了如何通过服务器返回的JSON数据动态生成一个表单。我们用ng-loop来遍历从服务器取回的所有数据。
                    由于不能动态生成name属性，而我们又需要这个属性做验证，所以在循环的过程中会为每一个字段都生成一个新表单。
                    由于AngularJS中用来取代<form>的ng-form指令可以嵌套，并且外部表单在所有子表单都合法之前一直处于不合法状态，
                        因此我们可以在动态生成子表单的同时使用表单验证功能。是的，鱼和熊掌可以兼得。
                        下面先看一下我们硬编码的JSON数据，把它假设成是从服务器返回的：
                        angular.module('myApp',[])
                        .controller('FormController',function($scope) {
                        $scope.fields = [
                        {placeholder: 'Username', isRequired: true},
                        {placeholder: 'Password', isRequired: true},
                        {placeholder: 'Email (optional)', isRequired: false}
                        ];
                        $scope.submitForm = function() {
                        alert("it works!");
                        };
                        });
                        下面用这些数据生成一个有验证功能的动态表单：
                        <form name="signup_form" ng-controller="FormController" ng-submit="submitForm()" novalidate>
                            <div ng-repeat="field in fields" ng-form="signup_form_input">
                                <input type="text"
                                       name="dynamic_input"
                                       ng-required="field.isRequired"
                                       ng-model="field.name"
                                       placeholder="{{field.placeholder}}" />
                                <div ng-show="signup_form_input.dynamic_input.$dirty &&signup_form_input.dynamic_input.$invalid">
                                        <span class="error"
                                              ng-show="signup_form_input.dynamic_input.$error.required">The field is required.</span>
                                </div>
                            </div>
                            <button type="submit"
                                    ng-disabled="signup_form.$invalid">
                                Submit All
                            </button>
                        </form>
                        input.ng-invalid {
                        border: 1px solid red;
                        }
                        input.ng-valid {
                        border: 1px solid green;
                        }s
         17. ng-click
                    ng-click用来指定一个元素被点击时调用的方法或表达式。
                        <div ng-controller="CounterController">
                            <button ng-click="count = count + 1"
                                    ng-init="count=0">
                                Increment
                            </button>
                            count: {{ count }}
                            <button ng-click="decrement()">
                                Decrement
                            </button>
                            <div>
                                angular.module('myApp',[])
                                .controller('CounterController', function($scope) {
                                $scope.decrement = function() {
                                $scope.count = $scope.count - 1;
                                };
                                })
         18. ng-select
                    ng-select用来将数据同HTML的<select>元素进行绑定。这个指令可以和ng-model以及
                    ng-options指令一同使用，构建精细且表现优良的动态表单。
                    ng-options的值可以是一个内涵表达式（comprehension expression），其实这只是一种有趣
                    的说法，简单来说就是它可以接受一个数组或对象，并对它们进行循环，将内部的内容提供给select标签内部的选项。它可以是下面两种形式。
                                 数组作为数据源：
                                 用数组中的值做标签；
                                 用数组中的值作为选中的标签；
                                 用数组中的值做标签组；
                                 用数组中的值作为选中的标签组。
                                 对象作为数据源：
                                 用对象的键值（key-value）做标签；
                                 用对象的键值作为选中的标签；
                                 用对象的键值作为标签组；
                                 用对象的键值作为选中的标签组。
                                下面看一个ng-select指令的实例：
                                <div ng-controller="CityController">
                                    <select ng-model="city"
                                            ng-options="city.name for city in cities">
                                        <option value="">Choose City</option>
                                    </select>
                                    Best City: {{ city.name }}
                                </div>
                                angular.module('myApp',[])
                                .controller('CityController',function($scope) {
                                $scope.cities = [
                                {name: 'Seattle'},
                                {name: 'San Francisco'},
                                {name: 'Chicago'},
                                {name: 'New York'},
                                {name: 'Boston'}
                                ];
                                });
         19. ng-submit
                  ng-submit用来将表达式同onsubmit事件进行绑定。这个指令同时会阻止默认行为（发送请求并重新加载页面），除非表单不含有action属性。
                                <form ng-submit="submit()" ng-controller="FormController">
                                    Enter text and hit enter:
                                    <input type="text" ng-model="person.name" name="person.name" />
                                    <input type="submit" name="person.name" value="Submit" />
                                    <code>people={{people}}</code>
                                    <ul ng-repeat="(index, object) in people">
                                        <li>{{ object.name }}</li>
                                    </ul>
                                </form>

                                angular.module('myApp',[])
                                .controller('FormController',function($scope) {
                                $scope.person = {
                                name: null
                                };
                                $scope.people = [];
                                $scope.submit = function() {
                                if ($scope.person.name) {
                                $scope.people.push({name: $scope.person.name});
                                $scope.person.name = '';
                                }
                                };
                                });
         20. ng-class
                 使用ng-class 动态设置元素的类，方法是绑定一个代表所有需要添加的类的表达式。重复的类不会添加。
                                当表达式发生变化，先前添加的类会被移除，新类会被添加。
                 下面的例子会用ng-class在一个随机数大于5时将.red类添加到一个div上：
                                <div ng-controller="LotteryController">
                                    <div ng-class="{red: x > 5}"
                                         ng-if="x > 5">
                                        You won!
                                    </div>
                                    <button ng-click="x = generateNumber()"
                                            ng-init="x = 0">
                                        Draw Number
                                    </button>
                                    <p>Number is: {{ x }}</p>
                                </div>
                                .red {
                                background-color: red;
                                }
                                angular.module('myApp',[])
                                .controller('LotteryController', function($scope) {
                                $scope.generateNumber = function() {
                                return Math.floor((Math.random()*10)+1);
                                };
                                });
         21. ng-attr-(suffix)
                    当AngularJS编译DOM时会查找花括号{{ some expression }}内的表达式。这些表达式会被自动注册到$watch服务中
                    并更新到$digest循环中，成为它的一部分：
                                <-- updated when`someExpression` on the$scope
                                is updated -->
                                <h1>Hello{{someExpression}}</h1>
                                有时浏览器会对属性会进行很苛刻的限制。SVG就是一个例子：
                                <svg>
                                    <circle cx="{{ cx }}"></circle>
                                </svg>
                                运行上面的代码会抛出一个错误，指出我们有一个非法属性。可以用ng-attr-cx来解决这
                                个问题。注意，cx位于这个名称的尾部。在这个属性中，通过用{{ }}来写表达式，达到前面提
                                到的目的。
                                <svg>
                                    <circle ng-attr-cx="{{ cx }}"><circle>
                                </svg>